package com.ruoyi.business.utils;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class HttpClient_Demo {
    public static void main(String[] args) {
//接口地址
        String url = "http://43.138.207.132:57880/saas-industry-test/api/zhsf/payOrder";
//应用账号
        String appID = "FDDXFSHSYY027348";
//密钥 签名私钥key
        String appKey = "96491564477290572987759675";
//接口对应的原始参数
        String data = "{\"busNo\":\"1939501920020467712\",\"busDateTime\":\"20250630095106593\",\"payer\":\"王兴菊\",\"tel\":\"19117891572\",\"idCardNo\":\"522724199805024422\",\"idCardType\":\"1101\",\"amount\":2000.00,\"notifyUrl\":\"http://124.220.26.214/engage-service/openapi/registerInfo\",\"payDataType\":\"02\",\"operator\":\"实际收款人就行，不固定\",\"templateCode\":\"1\",\"chargeDetail\":[{\"chargeCode\":\"513\",\"chargeName\":\"进修费\",\"std\":\"2000\",\"number\":1,\"amt\":2000.00}]}";
//版本号
        String version = "2.0";
//唯一值 请求随机标识
        String noise = UUID.randomUUID().toString().replaceAll("-", "");
        // 1.对data串Base64编码
        data = Base64.encodeBase64String(data.getBytes(Charset.forName("UTF-8")));

        //2. 做 AES/ECB/PKCS5Padding 返回16进制字符串
        String AESData = encrypt(data, appKey.substring(2, 18));

        //3. 生成sign = SHA512(appID+AESData+noise+version+appKey)返回16进制字符串
        String sign = sign(appID + AESData + noise + version + appKey);
        // 4、最终请求串
        Map<String, String> map = new HashMap<>();
        map.put("appid", appID);
        map.put("data", AESData);
        map.put("noise", noise);
        map.put("sign", sign);
        map.put("version", version);
        //------http请求调用
        try {
            HttpPost httpPost = new HttpPost(url);
            CloseableHttpClient client = HttpClients.createDefault();
            StringEntity entity = new StringEntity(new ObjectMapper().writeValueAsString(map), "utf-8");
            entity.setContentEncoding("UTF-8");
            entity.setContentType("application/json");
            httpPost.setEntity(entity);
            HttpResponse resp = client.execute(httpPost);
            if (resp.getStatusLine().getStatusCode() == 200) {
                String rev = EntityUtils.toString(resp.getEntity());
                //1. 返回结果json转对象或则map
                System.out.println("返回串--》" + rev);
                Map result = new ObjectMapper().readValue(rev, Map.class);
                String rdata = result.get("data").toString();
                String rnoise = result.get("noise").toString();
                // 2.返回结果验证安全
                String ysign = sign(appID + rdata + rnoise + version + appKey);
                String rsign = result.get("sign").toString();
                System.out.println("验签-》" + (StringUtils.equals(rsign, ysign)));
                // 3. 做 AES/ECB/PKCS5Padding 解密返回结果明文
                String restData = decrypt(rdata, appKey.substring(2, 18));
                System.out.println("返回业务数据--》" + restData);
                System.out.println("业务信息Base64解码--》" + new String(Base64.decodeBase64(restData), "UTF-8"));
            } else {
                System.out.println("请求失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * SHA512散列 返回16进制字符串
     *
     * @param data
     * @return
     */
    public static String sign(String data) {
        try {
            MessageDigest sha = MessageDigest.getInstance("SHA-512");
            sha.update(data.getBytes());
            byte[] byteBuffer = sha.digest();
            String sign = Hex.encodeHexString(byteBuffer);
            return sign;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    /*--------------------AES128------------------*/
    private static final String KEY_ALGORITHM = "AES";
    private static final String CHAR_SET = "UTF-8";
    /**
     * AES的密钥长度
     */
    private static final Integer SECRET_KEY_LENGTH = 128;
    /**
     * 加解密算法/工作模式/填充方式
     */
    private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";

    /**
     * AES加密操作
     *
     * @param content  待加密内容
     * @param password 加密密码
     * @return 返回Base64转码后的加密数据
     */
    public static String encrypt(String content, String password) {
        try {
            //创建密码器
            Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
            byte[] byteContent = content.getBytes(CHAR_SET);
            //初始化为加密密码器
            cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(password));
            return Hex.encodeHexString(cipher.doFinal(byteContent));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * AES解密操作
     *
     * @param encryptContent 加密的密文
     * @param password       解密的密钥
     * @return
     */
    public static String decrypt(String encryptContent, String password) {
        Cipher cipher = null;
        try {
            cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
            //设置为解密模式
            cipher.init(Cipher.DECRYPT_MODE, getSecretKey(password));
            //执行解密操作
            byte[] result = cipher.doFinal(Hex.decodeHex(encryptContent.toCharArray()));
            return new String(result);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 生成秘钥
     *
     * @param password 原始秘钥
     */
    private static SecretKeySpec getSecretKey(final String password) throws UnsupportedEncodingException {
        byte[] raw = password.getBytes("utf-8");
        return new SecretKeySpec(raw, "AES");
    }
}
